import React, { useState, useEffect, createContext, useContext, ReactNode } from 'react';
import ReactDOM from 'react-dom';

// 消息类型
export type MessageType = 'success' | 'error' | 'warning';

// 消息接口
interface MessageProps {
    type: MessageType;
    content: ReactNode;
    duration?: number;
    onClose?: () => void;
}

// 消息上下文接口
interface MessageContextProps {
    success: (content: ReactNode, duration?: number, onClose?: () => void) => void;
    error: (content: ReactNode, duration?: number, onClose?: () => void) => void;
    warning: (content: ReactNode, duration?: number, onClose?: () => void) => void;
}

// 创建消息上下文
const MessageContext = createContext<MessageContextProps | null>(null);

// 消息项组件
const MessageItem: React.FC<MessageProps & { id: string; onRemove: (id: string) => void }> = ({
    type,
    content,
    duration = 3000,
    id,
    onRemove,
    onClose,
}) => {
    useEffect(() => {
        const timer = setTimeout(() => {
            onRemove(id);
            if (onClose) onClose();
        }, duration);

        return () => clearTimeout(timer);
    }, [duration, id, onRemove, onClose]);

    // 图标映射
    const icons = {
        success: (
            <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
                <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd"></path>
            </svg>
        ),
        error: (
            <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
                <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd"></path>
            </svg>
        ),
        warning: (
            <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
                <path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd"></path>
            </svg>
        ),
    };

    // 类型样式映射
    const typeStyles = {
        success: 'bg-green-50 text-green-800 border-green-300',
        error: 'bg-red-50 text-red-800 border-red-300',
        warning: 'bg-yellow-50 text-yellow-800 border-yellow-300',
    };

    const iconStyles = {
        success: 'text-green-500',
        error: 'text-red-500',
        warning: 'text-yellow-500',
    };

    return (
        <div
            className={`flex items-center p-4 mb-4 border rounded-lg shadow-lg transition-all transform animate-slideIn ${typeStyles[type]}`}
            style={{ maxWidth: '400px' }}
        >
            <div className={`inline-flex items-center justify-center flex-shrink-0 w-8 h-8 rounded-lg ${iconStyles[type]}`}>
                {icons[type]}
            </div>
            <div className="ml-3 text-sm font-normal">{content}</div>
            <div
                className={`ml-auto -mx-1.5 -my-1.5 rounded-lg p-1.5 inline-flex h-8 w-8 ${typeStyles[type]} hover:opacity-75`}
                onClick={() => {
                    onRemove(id);
                    if (onClose) onClose();
                }}
            >
                <span className="sr-only">关闭</span>
                <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
                    <path fillRule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clipRule="evenodd"></path>
                </svg>
            </div>
        </div>
    );
};

// 消息容器组件
const MessageContainer: React.FC<{ children: ReactNode }> = ({ children }) => {
    return (
        <div
            className="fixed z-[10000] top-4 left-1/2 transform -translate-x-1/2 flex flex-col items-center"
            style={{ minWidth: '250px' }}
        >
            {children}
        </div>
    );
};

// 消息提供者组件
export const MessageProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
    const [messages, setMessages] = useState<Array<{ id: string; props: MessageProps }>>([]);

    // 添加消息
    const add = (props: MessageProps) => {
        const id = Date.now().toString();
        setMessages((prevMessages) => [...prevMessages, { id, props }]);
    };

    // 移除消息
    const remove = (id: string) => {
        setMessages((prevMessages) => prevMessages.filter((message) => message.id !== id));
    };

    // 创建消息方法
    const messageApi = {
        success: (content: ReactNode, duration?: number, onClose?: () => void) => {
            add({ type: 'success', content, duration, onClose });
        },
        error: (content: ReactNode, duration?: number, onClose?: () => void) => {
            add({ type: 'error', content, duration, onClose });
        },
        warning: (content: ReactNode, duration?: number, onClose?: () => void) => {
            add({ type: 'warning', content, duration, onClose });
        },
    };

    // 创建消息元素
    const messageElement = (
        <MessageContainer>
            {messages.map(({ id, props }) => (
                <MessageItem key={id} id={id} onRemove={remove} {...props} />
            ))}
        </MessageContainer>
    );

    return (
        <MessageContext.Provider value={messageApi}>
            {children}
            {ReactDOM.createPortal(messageElement, document.body)}
        </MessageContext.Provider>
    );
};

// 使用消息的钩子
export const useMessage = () => {
    const context = useContext(MessageContext);
    if (!context) {
        throw new Error('useMessage must be used within a MessageProvider');
    }
    return context;
};

// 添加全局样式
const style = document.createElement('style');
style.textContent = `
  @keyframes slideIn {
    from {
      transform: translateY(-20px);
      opacity: 0;
    }
    to {
      transform: translateY(0);
      opacity: 1;
    }
  }
  
  .animate-slideIn {
    animation: slideIn 0.3s ease-out forwards;
  }
`;
document.head.appendChild(style);

export default { useMessage, MessageProvider };
